/*
 * data_io.h
 * 数据IO管理模块头文件
 * 
 * 说明：该模块负责数据的发送、接收和格式化处理，支持文本和十六进制格式。
 */

#ifndef DATA_IO_H
#define DATA_IO_H

#include <QObject>
#include <QByteArray>
#include <QString>
#include <QStringList>
#include <QTimer>
#include <QDateTime>
#include <QSerialPort>

/**
 * @brief 接收数据块结构体
 */
struct ReceiveDataBlock {
    QByteArray rawData;         // 原始数据
    QString timestamp;          // 时间戳
    bool prependNewLine;        // 是否需要前置换行符
};

/**
 * @brief 数据统计结构体
 */
struct DataStatistics {
    quint64 sentBytes;          // 已发送字节数
    quint64 receivedBytes;      // 已接收字节数
    double receiveRate;         // 接收速率（字节/秒）
};

/**
 * @brief 数据IO管理类，负责数据的发送、接收和格式化
 * 
 * 该类提供了数据格式转换、数据收发处理等功能，支持文本和十六进制格式的
 * 数据处理，是串口调试工具的数据处理核心。
 */
class DataIO : public QObject
{
    Q_OBJECT

public:
    /**
     * @brief 构造函数
     * @param serialPort 串口对象指针
     * @param parent 父对象
     */
    explicit DataIO(QSerialPort *serialPort, QObject *parent = nullptr);
    
    /**
     * @brief 析构函数
     */
    ~DataIO();
    
    /**
     * @brief 读取串口数据
     */
    void readSerialData();
    
    /**
     * @brief 发送数据到串口
     * @param data 要发送的数据
     * @return 是否发送成功
     */
    bool sendData(const QByteArray &data);
    
    /**
     * @brief 根据输入文本和格式发送数据
     * @param inputText 输入文本
     * @param isHex 是否为十六进制格式
     * @return 是否发送成功
     */
    bool sendData(const QString &inputText, bool isHex);
    
    /**
     * @brief 格式化数据用于显示
     * @param data 数据
     * @param isHex 是否为十六进制格式
     * @return 格式化后的文本
     */
    QString formatDataForDisplay(const QByteArray &data, bool isHex);
    
    /**
     * @brief 从输入解析数据
     * @param input 输入文本
     * @param isHex 是否为十六进制格式
     * @return 解析后的数据
     */
    QByteArray parseDataFromInput(const QString &input, bool isHex);
    
    /**
     * @brief 批量刷新接收缓冲区到UI
     */
    void flushReceiveBuffer();
    
    /**
     * @brief 强制限制最大行数
     */
    void enforceMaxLines();
    
    /**
     * @brief 重新格式化并重显示所有数据
     */
    void reformatAndRedisplayData();
    
    /**
     * @brief 清空接收缓冲区
     */
    void clearReceiveBuffer();
    
    /**
     * @brief 设置自动发送状态
     * @param enabled 是否启用
     */
    void setAutoSendEnabled(bool enabled);
    
    /**
     * @brief 设置自动发送间隔
     * @param interval 间隔（毫秒）
     */
    void setAutoSendInterval(int interval);
    
    /**
     * @brief 设置十六进制发送模式
     * @param enabled 是否启用
     */
    void setHexSendEnabled(bool enabled);
    
    /**
     * @brief 设置十六进制接收模式
     * @param enabled 是否启用
     */
    void setHexReceiveEnabled(bool enabled);
    
    /**
     * @brief 设置时间戳启用状态
     * @param enabled 是否启用
     */
    void setTimestampEnabled(bool enabled);
    
    /**
     * @brief 设置自动滚动启用状态
     * @param enabled 是否启用
     */
    void setAutoScrollEnabled(bool enabled);
    
    /**
     * @brief 设置暂停接收状态
     * @param paused 是否暂停
     */
    void setPauseReceiving(bool paused);
    
    /**
     * @brief 设置最大保留行数
     * @param maxLines 最大行数
     */
    void setMaxRetainedLines(int maxLines);
    
    /**
     * @brief 获取统计信息
     * @return 统计信息
     */
    DataStatistics getStatistics() const;
    
    // 统计数据直接访问接口
    quint64 getReceivedBytesCount() const;
    quint64 getSentBytesCount() const;
    double getCurrentReceiveRate() const;
    
    /**
     * @brief 清空统计信息
     */
    void clearStatistics();
    
    /**
     * @brief 更新统计信息（用于状态栏显示）
     */
    void updateStatistics();
    
    /**
     * @brief 设置自动发送文本
     * @param text 要发送的文本
     */
    void setAutoSendText(const QString &text);
    
    /**
     * @brief 查找文本在接收缓冲区中
     * @param text 要查找的文本
     * @param caseSensitive 是否区分大小写
     * @return 包含该文本的行号列表
     */
    QList<int> findTextInReceiveBuffer(const QString &text, bool caseSensitive);
    
    /**
     * @brief 导出接收数据到文件
     * @param filePath 文件路径
     * @return 是否导出成功
     */
    bool exportReceiveDataToFile(const QString &filePath);
    
    /**
     * @brief 验证发送输入是否有效
     * @param input 输入文本
     * @param isHex 是否为十六进制格式
     * @return 是否有效
     */
    bool validateSendInput(const QString &input, bool isHex);
    // 接收缓冲访问接口
    bool isReceiveBufferEmpty() const;
    QStringList takeReceiveBufferLines();

signals:
    /**
     * @brief 数据接收信号
     * @param bytesCount 接收的字节数
     */
    void dataReceived(int bytesCount);
    
    /**
     * @brief 数据发送信号
     * @param bytesCount 发送的字节数
     */
    void dataSent(int bytesCount);
    
    /**
     * @brief 接收缓冲区准备好信号
     * @param lines 数据行列表
     */
    void receiveBufferReady(const QStringList &lines);
    
    /**
     * @brief 接收缓冲区清空信号
     */
    void receiveBufferCleared();
    
    /**
     * @brief 统计信息更新信号
     */
    void statisticsChanged();

private slots:
    /**
     * @brief 自动发送定时器超时处理
     */
    void onAutoSendTimerTimeout();
    
    /**
     * @brief 接收刷新定时器超时处理
     */
    void onReceiveFlushTimerTimeout();

private:
    QSerialPort *serialPort;              // 串口对象指针
    
    // 状态标志
    bool isHexSend;                       // 是否为十六进制发送
    bool isHexReceive;                    // 是否为十六进制接收
    bool isTimestampEnabled;              // 是否启用时间戳
    bool isAutoScrollEnabled;             // 是否启用自动滚动
    bool isAutoSend;                      // 是否启用自动发送
    bool pauseReceiving;                  // 是否暂停接收
    
    // 计数器
    quint64 sentBytesCount;               // 已发送字节数
    quint64 receivedBytesCount;           // 已接收字节数
    
    // 速率计算相关
    QDateTime lastStatsUpdateTime;        // 上次统计更新时间
    quint64 lastReceivedBytesSnapshot;    // 上次接收字节数快照
    
    // 自动发送相关
    QString autoSendText;                 // 自动发送文本
    QTimer *autoSendTimer;                // 自动发送定时器
    
    // 接收刷新定时器
    QTimer *receiveFlushTimer;            // 接收刷新定时器
    
    // 接收缓冲区
    QList<ReceiveDataBlock> receiveDataBlocks; // 接收数据块列表
    QStringList receiveBufferLines;       // 接收缓冲行列表
    
    // 配置参数
    int maxRetainedLines;                 // 最大保留行数
};

#endif // DATA_IO_H